<template>
	<u-popup v-model="value" :popup="false" @close="closePicker" mode="bottom" height="500">
		<view class="conbox record" v-if="value">			
			<view class="time">{{ showRecordTime }}</view>
			<view class="c999">最短{{ minTime }}秒，最长{{ maxTime }}秒</view>
			<view class="record-box u-flex">
				<view class="u-flex-1">
					<u-icon class="stop" :color="theme.bgColor" @click="stopVoice" v-if="_voicePath && playing == 1" name="pause-circle" size="70"></u-icon>
					<u-icon class="paly" :color="theme.bgColor" @click="playVoice" v-if="_voicePath && playing == 0" name="play-circle" size="70"></u-icon>
				</view>
				<view class="circle" :style="[{width: widthPx + 'px',height: widthPx + 'px'}]">
					<canvas
						class="canvas"
						:style="[{width: widthPx + 'px',height: widthPx + 'px'}]"
						canvas-id="bgcanvas"
					></canvas>
					<canvas
						class="canvas"
						:style="[{width: widthPx + 'px',height: widthPx + 'px'}]"
						canvas-id="canvas"
						@touchstart="start"
						@touchend="end"
						@touchcancel="cancel"
						@touchmove.stop.prevent="moveHandle">
						<text class="recording" :style="[recordBgColor,{width: rwidth + 'px',height: rwidth + 'px'}]"></text>
					</canvas>					
				</view>
				<view class="u-flex-1">
					<u-icon :color="theme.bgColor" class="confirm" @click="okClick" v-if="_voicePath" name="checkmark-circle" size="70"></u-icon>
				</view>
			</view>
			<view class="c666 fz32 domess">长按录音</view>
		</view>
	</u-popup>
</template>
<script>
const recorderManager = uni.getRecorderManager(); //录音
export default {
	name: 'fa-voices',
	props: {
		value: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			widthPx: uni.upx2px(200), // 转成px后的整个组件的背景宽度
			rwidth: uni.upx2px(160), // 转成px后的内图的宽
			frame: 30, // 执行绘画的频率，单位毫秒
			recordTime: 0, //录音时长
			recordTime1: 0, //播放录音倒计时
			centerXY: 0,
			yuanhuanW: 0,

			playing: 0, //是否播放中
			timeObj: null, //计时id
			drawObj: null, //画布动画id
			countdownObj: null, //倒计时id
			vioces: '',

			innerAudioContext: null,
			maxTime: 0,
			minTime: 0,
			
			progressContext: null,
			circleContext: null,
			is_start: false,

			circles: null
		};
	},
	computed: {
		showRecordTime() {
			var strs = '';
			var m = Math.floor(this.recordTime / 60);
			if (m < 10) strs = '0' + m;

			var s = this.recordTime % 60;
			strs += s < 10 ? ':0' + s : ':' + s;

			return strs;
		},
		_voicePath() {
			return this.vioces != '';
		},
		recordBgColor() {
			return {
				border: '1px dashed' + this.theme.bgColor,
				background:
					this.theme.bgColor +
					' url() no-repeat 50% 50%',
				backgroundSize: '50% 50%'
			};
		}
	},
	watch: {
		value(newValue, oldValue) {
			if(newValue){
				this.$nextTick(()=>{
					this.drawProgressBg();
					if(this.circles!=null){
						this.writeCircle()
					}
				})
			};
		}
	},
	mounted() {
		this.maxTime = this.vuex_config.max_recording_time || 10;
		this.minTime = this.vuex_config.min_recording_time || 2;
		
		this.centerXY = this.widthPx / 2;
		this.yuanhuanW = this.rwidth / 2 + 6; //圆环的半径  中间图片的宽度/2 + 6

		if (!this.innerAudioContext) {
			this.innerAudioContext = uni.createInnerAudioContext(); //播放;
		}		
		//录音错误事件
		recorderManager.onError(res => {
			this.$u.toast(res.errMsg);
		});
	},
	beforeDestroy() {
		if(this.innerAudioContext){
			this.innerAudioContext.destroy();			
		}
	},
	methods: {
		moveHandle() {
			return false;
		},
		//关闭组件
		closePicker() {			
			this.$emit('input', false);
			this.stopVoice();
		},
		//点击确定
		okClick() {
			// #ifdef APP-PLUS
			this.vioces = Object.assign(this.vioces, {
				duration: this.recordTime * 1000
			});
			// #endif
			this.$emit('okClick', this.vioces);
			//关闭
			this.closePicker();
		},		
		//背景圆圈
		drawProgressBg() {			
			let ctx = this.circleContext;
			if(!ctx){
				ctx = uni.createCanvasContext('bgcanvas', this);
				this.circleContext = ctx;
			}
			// 录音过程圆圈动画的背景园
			ctx.setLineWidth(5);
			ctx.setStrokeStyle('#ececec');
			ctx.beginPath();
			ctx.arc(this.centerXY, this.centerXY, this.yuanhuanW, 0, 2 * Math.PI);
			ctx.stroke();
			ctx.draw();
		},
		start() {			
			this.is_start = true;
			this.stopVoice();
			this.$u.debounce(() => {
				if (!this.is_start) {
					return;
				}
				//录音停止事件
				recorderManager.onStop((res)=>{			
					if (this.recordTime < this.minTime) {
						let ctx = this.progressContext;
						if (ctx) {					
							ctx.clearRect(0, 0, this.widthPx, this.widthPx)
						}
						//==小于5秒==;
						this.recordTime = 0;				
						uni.showToast({
							title: '不能小于' + this.minTime + '秒,请重新录制',
							icon: 'none'
						});
						return false;
					}
					this.vioces = res;
				});
				this.recordTime = 0;
				this.record();
			}, 300);
		},
		end() {					
			this.is_start = false;
			this.recordTime1 = this.recordTime;
			clearInterval(this.timeObj); //清除计时器
			clearInterval(this.drawObj); //清除画布动画			
			recorderManager.stop();
		},
		//长按事件
		record: function() {
			let that = this;			
			// 开始录音
			recorderManager.start({
				format: this.vuex_config.recording_format || 'wav'
			});
			that.timeObj = setInterval(function() {
				that.recordTime+=1;				
				if (that.recordTime == that.maxTime) that.end();
			}, 1000);
			// 录音过程圆圈动画			
			let angle = -0.5;
			that.drawObj = setInterval(function() {
				that.circles = (angle += 2 / ((that.maxTime * 1000) / that.frame)) * Math.PI;
				that.writeCircle()
			}, that.frame);
		},
		//画圆圈
		writeCircle(){			
			let ctx = this.progressContext;
			if (!ctx) {
				ctx = uni.createCanvasContext('canvas', this);
				this.progressContext = ctx;
			}
			ctx.setLineCap('round');
			ctx.setLineWidth(5);
			ctx.setStrokeStyle(this.theme.bgColor);				
			ctx.beginPath();
			ctx.arc(this.centerXY, this.centerXY, this.yuanhuanW, -0.5 * Math.PI, this.circles, false);
			ctx.stroke();
			ctx.draw();
		},
		//打断
		cancel() {
			this.is_start = false;
			clearInterval(this.timeObj); //清除计时器
			clearInterval(this.drawObj); //清除画布动画
			recorderManager.stop();
		},
		playVoice() {			
			if (this.vioces && this.vioces.tempFilePath && this.playing === 0) {
				this.innerAudioContext.src = this.vioces.tempFilePath;
				this.innerAudioContext.play();
				this.playing = 1;
				this.recordTime = this.recordTime1;
				this.countdownObj = setInterval(() => {
					this.recordTime--;
					if (this.recordTime === 0) {
						this.stopVoice();
						return;
					}
				}, 1000);
			}
		},
		stopVoice() {
			this.innerAudioContext.stop();
			this.playing = 0;
			this.recordTime = this.recordTime1;
			clearInterval(this.countdownObj);
		}
	}
};
</script>

<style lang="scss">
.conbox {
	overflow: hidden;
	width: 100%;
	height: 100%;
	.c666 {
		color: #666;
	}
	.c999 {
		color: #999;
	}

	.fz32 {
		font-size: 32rpx;
	}

	text-align: center;

	.time {
		text-align: center;
		font-size: 60rpx;
		color: #000;
		line-height: 100rpx;
		margin-top: 50rpx;
	}
	.domess {
		margin-bottom: 50rpx;
	}

	.record-box {
		display: flex;
		flex-direction: row;
		justify-content: center;
		width: 100vw;
	}
	.circle {
		position: relative;
		/* #ifndef APP-NVUE */
		display: inline-flex;
		/* #endif */
		align-items: center;
		justify-content: center;
		.canvas {
			position: absolute;
			.recording {
				position: absolute;
				top: 20rpx;
				left: 20rpx;
				border-radius: 100rpx;
				z-index: 100;
			}
		}
	}
}
</style>
